package com.funkids.prxis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.funkids.prxis.entity.SysMenu;
import com.funkids.prxis.entity.SysRole;
import com.funkids.prxis.entity.SysUser;
import com.funkids.prxis.mapper.SysRoleMapper;
import com.funkids.prxis.mapper.SysUserMapper;
import com.funkids.prxis.mapper.SysUserRoleMapper;
import com.funkids.prxis.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.funkids.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author funkids
 * @since 2023-03-08
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    SysRoleMapper sysRoleMapper;

    @Autowired
    SysRoleServiceImpl roleService;

    @Autowired
    SysMenuServiceImpl sysMenuService;

    @Autowired
    RedisUtils redisUtils;

    @Override
    public SysUser getByUsername(String userName) {
        return sysUserMapper.getByUsername(userName);
    }

    @Override
    public String getAuthorityInfoByid(Long userid) {

        SysUser sysUser = sysUserMapper.selectById(userid);

        //获取角色信息
        String authority = "";


        if (redisUtils.hasKey("GrantedAuthority:"+ sysUser.getUserName())) {
            authority = (String) redisUtils.get("GrantedAuthority:" + sysUser.getUserName());
        } else {
            List<Long> roleIds = sysUserRoleMapper.getRoleidByUserid(userid);
            if(roleIds.size()>0){

                List<SysRole> roles = roleService.listByIds(roleIds);
                /**
                 * strean()：适用于对整个List中的元素进行统一的操作
                 * map(r->(r.ops()))：将流中的所有元素以r.ops的方式返回
                 * collect(Collectors.ops（）)：将前面操作过后的流中的数据收集起来，并以Collectors代指，最后返回经再次操作过后的Collectors.ops（）
                 */

                String roleCodes = roles.stream().map(r -> "ROLE_" + r.getRoleCode()).collect(Collectors.joining(","));
                authority = roleCodes.concat(",");
            }

            //获取菜单信息
            List<Long> menuIds = getMenuIds(userid);
            if(menuIds.size()>0){
                List<SysMenu> menus = sysMenuService.listByIds(menuIds);
                String menuPerms = menus.stream().map(m ->m.getPerms()).collect(Collectors.joining(","));
                authority = authority.concat(menuPerms);
            }
            redisUtils.set("GrantedAuthority:" + sysUser.getUserName(), authority, 60 * 60);
        }

        return authority;
    }

    @Override
    public List<Long> getMenuIds(Long userid) {
        return sysUserMapper.getMenuIds(userid);
    }

    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtils.del("GrantedAuthority:" + username);
    }

    @Override
    public void clearUserAuthorityInfoByRoleId(Long roleId) {

        List<SysUser> sysUsers = this.list(new QueryWrapper<SysUser>()
                .inSql("id", "select user_id from sys_user_role where role_id = " + roleId));

        sysUsers.forEach(u -> {
            this.clearUserAuthorityInfo(u.getUserName());
        });

    }

    @Override
    public void clearUserAuthorityInfoByMenuId(Long menuId) {
        List<SysUser> sysUsers = sysUserMapper.listBymenuId(menuId);

        sysUsers.forEach(u -> {
            this.clearUserAuthorityInfo(u.getUserName());
        });
    }

}
